import { deepClone, titleCase } from '@/utils/index'
import ruleTrigger from './ruleTrigger'
import { exportDefault } from '@/utils/index'

const units = {
    KB: '1024',
    MB: '1024 / 1024',
    GB: '1024 / 1024 / 1024'
}

let confGlobal
const inheritAttrs = {
    file: '',
    dialog: 'inheritAttrs: false,'
}

/**
 * 组装JS
 * formConfig: 整个表单配置
 * type： 生成类型，文件或弹窗
 */
export function makeUpJs(formConfig, type) {
    confGlobal = formConfig = deepClone(formConfig)
    const dataList = [];
    const ruleList = [];
    const optionsList = [];
    const propsList = [];
    const methodList = mixinMethod(type)
    const uploadVarList = []
    const created = []

    formConfig.fields.forEach(el => {
        buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList, created)
    })

    const script = buildexport(
        formConfig,
        type,
        dataList.join('\n'),
        ruleList.join('\n'),
        optionsList.join('\n'),
        uploadVarList.join('\n'),
        propsList.join('\n'),
        methodList.join('\n'),
        created.join('\n')
    ) 
    confGlobal = null
    return script

}


// 构建组件的属性
function buildAttributes(scheme, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) {
    const config = scheme.__config__
    const slot = scheme.__slot__
    buildData(scheme,dataList)
    buildRules(scheme, ruleList)
    // 特殊处理options属性
    if(scheme.options || (slot && slot.options && slot.options.length)) {
        buildOptions(scheme, optionsList)
        if(config.dataType === 'dynamic') {
            const model = `${scheme.__vModel__}Options`
        }
    }

     // 处理props
    if (scheme.props && scheme.props.props) {
        buildProps(scheme, propsList)
    }

    // 构建子级组件属性
    if (config.children) {
        config.children.forEach(item => {
        buildAttributes(item, dataList, ruleList, optionsList, methodList, propsList, uploadVarList, created)
        })
    }

}


// 构建data
function buildData(scheme, dataList) {
    const config = scheme.__config__
    if(scheme.__vModel__ === undefined) return
    const defaultValue = JSON.stringify(config.defaultValue)
    dataList.push(`${scheme.__vModel__}: ${defaultValue}`);
}

// 构建校验规则
function buildRules(scheme, ruleList) {
    const config = scheme.__config__
    // 没有使用v-model绑定事件的 规则也不需要构建了
    if(scheme.__vModel__ === undefined) return
    const rules = []
    if(ruleTrigger[config.tag]) {
        if(config.required) {
            const type = Array.isArray(config.defaultValue) ? 'type: \'array\',':''
            // 错误提示信息
            let message = Array.isArray(config.defaultValue) ? `请至少选择一个${config.label}`: scheme.placeholder
            if(message === undefined) message = `${config.label}不能为空`
            rules.push(`{ required: true, ${type} message: '${message}', trigger: '${ruleTrigger[config.tag]}'}`) 
        }
        // 正则校验规则
        if(config.regList && Array.isArray(config.regList)) {
            config.regList.forEach(item => {
                if(item.pattern) {
                    rules.push(
                        `{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${ruleTrigger[config.tag]}'}`
                    )
                }
            })
        }
        ruleList.push(`${scheme.__vModel__}: [${rules.join(',')}]`)
    }
}

// 构建options
function buildOptions(scheme, optionsList) {
    if(scheme.__vModel__ === undefined) return
    let { options } = scheme 
    if(!options) options = scheme.__slot__.options
    if(scheme.__config__.dataType === 'dynamic') { options = []} 
    // 构建的唯一的属性 在template中取下拉属性 也可以取${scheme.__vModel__}Options属性
    const str = `${scheme.__vModel__}Options: ${JSON.stringify(options)}`
    optionsList.push(str)
}


function buildProps(scheme, propsList) {
    const str = `${scheme.__vModel__}Props: ${JSON.stringify(scheme.props.props)}`
    propsList.push(str)
}

// 混入处理函数
function mixinMethod(type) {
    const list = []; const
      minxins = {
        file: confGlobal.formBtns ? {
          submitForm: `submitForm() {
          this.$refs['${confGlobal.formRef}'].validate(valid => {
            if(!valid) return
            // TODO 提交表单
          })
        },`,
          resetForm: `resetForm() {
          this.$refs['${confGlobal.formRef}'].resetFields()
        },`
        } : null,
        dialog: {
          onOpen: 'onOpen() {},',
          onClose: `onClose() {
          this.$refs['${confGlobal.formRef}'].resetFields()
        },`,
          close: `close() {
          this.$emit('update:visible', false)
        },`,
          handelConfirm: `handelConfirm() {
          this.$refs['${confGlobal.formRef}'].validate(valid => {
            if(!valid) return
            this.close()
          })
        },`
        }
      }
  
    const methods = minxins[type]
    if (methods) {
      Object.keys(methods).forEach(key => {
        list.push(methods[key])
      })
    }
  
    return list
  }

// el-upload beforeUpload
function buildBeforeUpload(scheme) {
    const config = scheme.__config__
    const unitNum = units[config.sizeUnit];
    let rightSizeCode = '';
    let acceptCode = '';
    const returnList = [];
    // 文件大小的限制
    if(config.fileSize) {
        rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${config.fileSize}
        if(!rightSizeCode) {
            this.$message.error('文件大小超过${config.fileSize}${config.sizeUnit}')
        }`
        returnList.push('isRightSize');
    }
    // 文件类型的限制
    if(scheme.accept) {
        acceptCode = `let isAccept = new RegExp('${scheme.accept}').test(file.type)
        if(!isAccept) {
            this.$message.error('应该选择${scheme.accept}类型的文件')
        }`
        returnList.push('isAccept')
    }
    // 上传
    const str = `${scheme.__vModel__}BeforeUpload(file) {
        ${rightSizeCode}
        ${acceptCode}
        return ${returnList.join('&&')}
    }`
    return returnList.length ? str : ''
}

// function buildOptionMethod(methodName, model, methodList, scheme) {
//     const config = scheme.__config__
//     const str = `${methodName}() {
//         this.$axios({
//             method: '${config.method}',
//             url: '${config.url}'
//         }).then(resp => {
//             var {} = resp
//             this.${model} = data.${config.dataPath}
//         })
//     }`
//     methodList.push(str)
// }

// js整体拼接
function buildexport(conf, type, data, rules, selectOptions, uploadVar, props, methods, created) {
    const str = `${exportDefault} {
        ${inheritAttrs[type]}
        components: {},
        props: [],
        data() {
            return {
                ${conf.formModel}; {
                    ${data}
                },
                ${conf.formRules}: {
                    ${rules}
                },
                ${uploadVar}
                ${selectOptions}
                ${props}
            }
        },
        computed: {},
        watch: {},
        created() {
            ${created}
        },
        mounted() {},
        methods: {
            ${methods}
        }
    }`
    return str
}